/**
 *  Copyright 2009 Henning Teek, Ingo Renner
 *  
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *  
 *  http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. 
 */
package com.googlecode.chigs.domain;

import java.util.List;

import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.synyx.hades.domain.AbstractPersistable;

import com.googlecode.chigs.web.common.UncheckedRuntimeException;

/**
 * @author Ingo Renner
 * @author Henning Teek
 */
@Entity
@Table(uniqueConstraints={@UniqueConstraint(columnNames={"major", "minor", "variant_id", "product_id"})})
@NamedQueries({
	@NamedQuery(name = "Version.findByAll", query = "from Version o"),
	@NamedQuery(name = "Version.findByModule", query = "select distinct o from Version o, in (o.revisions) r where r.module = ?")})
public class Version extends AbstractPersistable<Long> {
	private int major;
	private int minor;
	
	@ManyToOne
	private Product product;

	@ManyToOne
	private Variant variant;

	@OneToMany(mappedBy = "version")
	private List<ConfigLocation> configLocations;
	
	@OneToMany(mappedBy = "version")
	private List<Revision> revisions;
	
	@OneToMany(mappedBy = "version")
	private List<ConfigRevision> configRevisions;
	
	public int getMajor() {
		return major;
	}

	public void setMajor(int major) {
		if (major < 0) {
			throw new UncheckedRuntimeException("Major Anteil der Version darf nicht kleiner 0 sein.");
		}
		this.major = major;
	}

	public int getMinor() {
		return minor;
	}

	public void setMinor(int minor) {
		if (minor < 0) {
			throw new UncheckedRuntimeException("Minor Anteil der Version darf nicht kleiner 0 sein.");
		}
		this.minor = minor;
	}

	public String getVersion() {
		return getMajor() + "." + getMinor() + getVariantString();
	}

	private String getVariantString() {
		return getVariant() == null ? "" : "-" + getVariant().getName();
	}

	public void setProduct(Product product) {
		this.product = product;
	}

	public Product getProduct() {
		return product;
	}

	public Variant getVariant() {
		return variant;
	}

	public void setVariant(Variant variant) {
		this.variant = variant;
	}

	public void setConfigLocations(List<ConfigLocation> configLocations) {
		this.configLocations = configLocations;
	}

	public List<ConfigLocation> getConfigLocations() {
		return configLocations;
	}

	public void setRevisions(List<Revision> revisions) {
		this.revisions = revisions;
	}

	public List<Revision> getRevisions() {
		return revisions;
	}

	public void setConfigRevisions(List<ConfigRevision> configRevisions) {
		this.configRevisions = configRevisions;
	}

	public List<ConfigRevision> getConfigRevisions() {
		return configRevisions;
	}

	@Override
	public String toString() {
		return String.format("Version [major=%s, minor=%s, product=%s, variant=%s, getId()=%s]",
			major, minor, product, variant, getId());
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result
				+ ((configLocations == null) ? 0 : configLocations.hashCode());
		result = prime * result
				+ ((configRevisions == null) ? 0 : configRevisions.hashCode());
		result = prime * result + major;
		result = prime * result + minor;
		result = prime * result + ((product == null) ? 0 : product.hashCode());
		result = prime * result
				+ ((revisions == null) ? 0 : revisions.hashCode());
		result = prime * result + ((variant == null) ? 0 : variant.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (!super.equals(obj)) {
			return false;
		}
		if (!(obj instanceof Version)) {
			return false;
		}
		Version other = (Version) obj;
		if (configLocations == null) {
			if (other.configLocations != null) {
				return false;
			}
		} else if (!configLocations.equals(other.configLocations)) {
			return false;
		}
		if (configRevisions == null) {
			if (other.configRevisions != null) {
				return false;
			}
		} else if (!configRevisions.equals(other.configRevisions)) {
			return false;
		}
		if (major != other.major) {
			return false;
		}
		if (minor != other.minor) {
			return false;
		}
		if (product == null) {
			if (other.product != null) {
				return false;
			}
		} else if (!product.equals(other.product)) {
			return false;
		}
		if (revisions == null) {
			if (other.revisions != null) {
				return false;
			}
		} else if (!revisions.equals(other.revisions)) {
			return false;
		}
		if (variant == null) {
			if (other.variant != null) {
				return false;
			}
		} else if (!variant.equals(other.variant)) {
			return false;
		}
		return true;
	}
}
